<?php
/**
 * Created by PhpStorm.
 * User: XT
 * Date: 2017/4/19
 * Time: 11:08
 */
namespace server;

use core\App;
use core\http\Response;
use core\http\Request;
use core\Exception;

class httpServer {

    protected $server;

    protected static $instance;

    public function __construct()
    {
        $this->server = new \swoole\http\server('0.0.0.0', 9501);
    }

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new static();
        }
        return self::$instance;
    }

    public function setConfig(array $config = [])
    {
        if (!empty($config)) {
            $this->server->set($config);
        }
        return $this;
    }

    public function initialize()
    {
        $this->server->on('start', array($this, 'start'));
        $this->server->on('workerStart', array($this, 'workerStart'));
        $this->server->on('workerError', array($this, 'workerError'));
        $this->server->on('workerStop', array($this, 'workerStop'));
        $this->server->on('request', array($this, 'request'));

        return $this;
    }

    /**
     * Fatal Error的捕获
     *
     */
    public function handleFatal()
    {
        $error = error_get_last();
        if (!isset($error['type'])) {
            return;
        }
        switch ($error['type']) {
            case E_ERROR:
            case E_PARSE:
            case E_DEPRECATED:
            case E_CORE_ERROR:
            case E_COMPILE_ERROR:
                break;
            default:
                return;
        }
        $message = $error['message'];
        $file    = $error['file'];
        $line    = $error['line'];
        $log     = "\n异常提示：$message ($file:$line)\nStack trace:\n";
        $trace   = debug_backtrace(1);
        foreach ($trace as $i => $t) {
            if (!isset($t['file'])) {
                $t['file'] = 'unknown';
            }
            if (!isset($t['line'])) {
                $t['line'] = 0;
            }
            if (!isset($t['function'])) {
                $t['function'] = 'unknown';
            }
            $log .= "#$i {$t['file']}({$t['line']}): ";
            if (isset($t['object']) && is_object($t['object'])) {
                $log .= get_class($t['object']) . '->';
            }
            $log .= "{$t['function']}()\n";
        }

        Response::getInstance()->status(500);
        Response::getInstance()->end($log);

    }

    public function run()
    {
        $this->server->start();
    }

    public function start(\swoole_server $server)
    {
        date_default_timezone_set('Asia/Shanghai');
    }

    public function workerStart(\swoole_server $server, $worker_id)
    {
        require __DIR__ . '/../bootstrap/bootstrap.php';
    }

    public function shutdown(\swoole_server $server)
    {

    }

    public function workerStop(\swoole_server $server, $worker_id)
    {

    }

    public function workerError(\swoole_server $server, $worker_id)
    {

    }

    public function request(\swoole_http_request $request, \swoole_http_response $response)
    {
        //请求过滤
        if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {
            return $response->end();
        }
		Request::getInstance($request);
        Response::getInstance($response);

        // 页面缓存
        ob_start();
        ob_implicit_flush(0);

		try {
			App::run();
		} catch (Exception $e) {
			$GLOBALS['exception'] = $e;
			App::error();
		}

        $result = ob_get_contents();
        ob_end_clean();
        Response::getInstance()->end($result);

    }
}


httpServer::getInstance()->setConfig(
    [
        'worker_num' => 4,    //开启两个worker进程
        'max_request' => 1,   //每个worker进程max request设置为3次
        'dispatch_mode' => 3,
        'daemonize' => 0,
        'log_file' => __DIR__ . '/../runtime/log/' . date('Y-m-d') . '.log',
    ]
)->initialize()->run();
